import 'package:dio/dio.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flustars/flustars.dart' hide ScreenUtil;
import 'package:get/get.dart' hide Response;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:sp_util/sp_util.dart';
import '../config/config.dart';
import '../store/main.dart';
/*
 * 封装 restful 请求
 *
 * GET、POST、DELETE、PATCH
 * 主要作用为统一处理相关事务：
 *  - 统一处理请求前缀；
 *  - 统一打印请求信息；
 *  - 统一打印响应信息；
 *  - 统一打印报错信息；
 */
class HttpUtils {

	/// 当前页面context 供插入UI用，比如toast
	static BuildContext? context;

    /// global dio object
    static Dio? dio;

    static String env="dev";

    /// default options
    // ignore: non_constant_identifier_names
    static String API_PREFIX = ProjectConfig.apiDomain;
    static const int CONNECT_TIMEOUT = 600000;
    static const int RECEIVE_TIMEOUT = 30000;
    static const String Content_Type='application/json;charset=utf-8';//'application/json;charset=utf-8';

    /// http request methods
    static const String GET = 'get';
    static const String POST = 'post';
    static const String PUT = 'put';
    static const String PATCH = 'patch';
    static const String DELETE = 'delete';

    static MainStore mainStore = Get.find<MainStore>();

    /// request method
    static Future<Map<String, dynamic>> request(String url, {data, method}) async {

        method = method ?? 'GET';

        /// 打印请求相关信息：请求地址、请求方式、请求参数

        LogUtil.d('请求参数：' + data.toString());

        Dio? dio = createInstance();
        Map<String, dynamic> result;

        String? token =SpUtil.getString('token');

        LogUtil.d('请求域名：【' + API_PREFIX +'】',tag: "HttpClient");
        LogUtil.d('请求地址：【' + method + '  ' + url + '】',tag: "HttpClient");
        LogUtil.d('请求token：【${token??null}】',tag: "HttpClient");

        Response? response ;

        try {
          if(method=='GET'){
                response =await dio?.get(url,queryParameters: data);
                LogUtil.d(response,tag:"response");
            }
            if(method=='POST'){
                data = data ?? {};
                response =await dio?.post(url,data: data);
            }
        } on DioError catch (e) {
            LogUtil.d(e.error,tag: "接口报错");
            response=e.response;
        }
        if(response==null){
            result ={"code":1};
        }else{
            result = response.data;
            LogUtil.d(response.toString(),tag: "接口响应");
        }
        return result;
    }

    /// 创建 dio 实例对象
    static Dio? createInstance() {
        if (dio == null) {
            /// 全局属性：请求前缀、连接超时时间、响应超时时间
            BaseOptions options = new BaseOptions(
                baseUrl: API_PREFIX,
                connectTimeout: CONNECT_TIMEOUT,
                receiveTimeout: RECEIVE_TIMEOUT,
                contentType: Content_Type
            );

            dio = new Dio(options);
            dio?.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
                options.headers={
                    "authorization":SpUtil.getString("token")
                };
                return handler.next(options);
            }, onResponse: (response, handler) {
                if (response != null) {
                    if(response.data['code']!=0){
                        SmartDialog.showToast(response.data['message'],alignment: Alignment.center);
                    }
                    return handler.next(response);
                } else {
                    return null;
                }
            }, onError: (DioError e, handler) async {
                if (e.response?.statusCode == 401) {//catch the 401 here
                    LogUtil.d("未登录");
                    resetLoginState();
                    handler.next(e);
                } else if(e.response?.statusCode == 403){
                    LogUtil.d("登录过期");
                    resetLoginState();
                    handler.next(e);
                }else {
                    handler.next(e);
                }
            }));
        }
        return dio;
    }

    static resetLoginState(){
        SpUtil.remove("token");
        mainStore.isLogin=false;
        mainStore.update();
    }

    /// 清空 dio 对象
    static clear() {
        dio = null;
    }
}
